//
//  RouterManager.m
//  NetworkDemo
//
//  Created by InitialC on 2017/5/3.
//  Copyright © 2016年 InitialC. All rights reserved.
//

#import "CNetRequestManager.h"
#import "MGJRouter.h"
#import "NetRouterManager.h"

#import "YYCache.h"

NSString * const SPHttpCache = @"SPHttpCache";
#ifdef DEBUG
#define NetCLog(...) NSLog(__VA_ARGS__)
#else
#define NetCLog(...)
#endif
@implementation NetRouterManager
+ (void)load {
    
    [self addNetWorkingListen];
    [self reachabilityStatusChange];
    [self getReachabilityStatus];
    [self setAuthorizationTokenListen];
    [self addNetworkingRequestListen];

}

+ (YYCache *)cacheYY {
    static YYCache *cache = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        cache = [[YYCache alloc] initWithName:SPHttpCache];
        cache.memoryCache.shouldRemoveAllObjectsOnMemoryWarning = YES;
        cache.memoryCache.shouldRemoveAllObjectsWhenEnteringBackground = YES;
    });
    return cache;
}
//判断一个URL是否在请求中
+ (void)addNetworkingRequestListen {
    [MGJRouter registerURLPattern:@"yanxi://UrlIsRequesting" toObjectHandler:^id(NSDictionary *routerParameters) {
        NSDictionary *userInfo = routerParameters[MGJRouterParameterUserInfo];
        NSString *url = userInfo[@"url"]?:@"";
        BOOL isRequest = [CNetRequestManager urlIsRequest:url];
        return @(isRequest);
    }];
}

+ (void)addNetWorkingListen {
    
    // 错误码管理
    
    
    [MGJRouter registerURLPattern:@"yanxi://GeneralRequest" toHandler:^(NSDictionary *routerParameters) {
        NSDictionary *userInfo = routerParameters[MGJRouterParameterUserInfo];
        NetCLog(@"网络请求消息 == %@", userInfo);
        //空格及中文处理
        NSString *url = userInfo[@"url"];
        
        NSDictionary *dic = userInfo[@"parameters"];
        NSString *type = [userInfo[@"type"] lowercaseString];
        //是否缓存
        BOOL isCache = [userInfo[@"isCache"] boolValue];
        void (^completion)(id result) = routerParameters[MGJRouterParameterCompletion];
        NSString *cacheUrl = nil;
        if(isCache == TRUE) {
             cacheUrl = [self urlDictToStringWithUrlStr:url WithDict:dic];
           NetCLog(@"\n\n 缓存网址 \n\n %@ \n\n 缓存网址 \n\n",cacheUrl);
            //设置YYCache属性

            id cacheData;
            if (isCache) {
                //根据网址从Cache中取数据
                cacheData = [[self cacheYY] objectForKey:cacheUrl];
                
                if (cacheData != nil) {
                    [self returnDataWithRequestData:cacheData withCompletion:completion];
                }
            }
            

        }
        
        if([CNetRequestManager networkReachabilityStatus] == 0) {
            NetCLog(@"无网络请求");
            NSError *error = [NSError errorWithDomain:@"无网络请检查网络" code:10000 userInfo:nil];
            [self failureEvent:error withCompletion:completion];
            return ;
        }
        
        if ([type isEqualToString:@"post"]) {
            [CNetRequestManager CPOST:url parameters:dic success:^(NSDictionary * _Nonnull dict, BOOL success) {
                [self successEvent:dict isCache:isCache withCacheKey:cacheUrl withCompletion:completion];
            } failure:^(NSError * _Nonnull error) {
                [self failureEvent:error withCompletion:completion];
            }];

        }
        else if([type isEqualToString:@"get"]) {
            [CNetRequestManager CGET:url parameters:dic success:^(NSDictionary * _Nonnull dict, BOOL success) {
                [self successEvent:dict isCache:isCache withCacheKey:cacheUrl withCompletion:completion];

            } failure:^(NSError * _Nonnull error) {
                [self failureEvent:error withCompletion:completion];

            }];
        }
        else if([type isEqualToString:@"cancel"]) {
            [CNetRequestManager cancelRequest:url];
        }
        else if([type isEqualToString:@"put"]) {
            [CNetRequestManager CPUT:url parameters:dic success:^(NSDictionary * _Nonnull dict, BOOL success) {
                [self successEvent:dict   withCompletion:completion];
                
            } failure:^(NSError * _Nonnull error) {
                [self failureEvent:error withCompletion:completion];
                
            }];
        }
        else if([type isEqualToString:@"patch"]) {
            [CNetRequestManager CPATCH:url parameters:dic success:^(NSDictionary * _Nonnull dict, BOOL success) {
                [self successEvent:dict  withCompletion:completion];
                
            } failure:^(NSError * _Nonnull error) {
                [self failureEvent:error withCompletion:completion];
                
            }];
            
        }
        else if([type isEqualToString:@"delete"]) {
            [CNetRequestManager CDELETE:url parameters:dic success:^(NSDictionary * _Nonnull dict, BOOL success) {
                [self successEvent:dict  withCompletion:completion];
                
            } failure:^(NSError * _Nonnull error) {
                [self failureEvent:error withCompletion:completion];
                
            }];
        }
        else if([type isEqualToString:@"download"]) {
            
            
            [CNetRequestManager downloadWithUrlSring:url savePath:userInfo[@"savePath"] progress:^(NSProgress * _Nonnull downloadProgress) {
                
                
                void (^DownloadProgress)(NSProgress *progress)  = userInfo[@"DownloadProgress"];
                if (DownloadProgress) {
                    DownloadProgress(downloadProgress);
                }
                
            } completionHandler:^(NSString *filePath, NSError *error) {
               
                if (error == nil) {
                    [self successEvent:@{@"filePath":filePath,@"code":@(200)}  withCompletion:completion];
                }
                else
                {
                    [self failureEvent:error withCompletion:completion];
                }
            }];
        }
        
    }];

}
/**
 *  拼接post请求的网址
 *
 *  @param urlStr     基础网址
 *  @param parameters 拼接参数
 *
 *  @return 拼接完成的网址
 */
+ (NSString *)urlDictToStringWithUrlStr:(NSString *)urlStr WithDict:(NSDictionary *)parameters {
    if (!parameters) {
        return urlStr;
    }
    
    
    NSMutableArray *parts = [NSMutableArray array];
    //enumerateKeysAndObjectsUsingBlock会遍历dictionary并把里面所有的key和value一组一组的展示给你，每组都会执行这个block 这其实就是传递一个block到另一个方法，在这个例子里它会带着特定参数被反复调用，直到找到一个ENOUGH的key，然后就会通过重新赋值那个BOOL *stop来停止运行，停止遍历同时停止调用block
    [parameters enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        //接收key
        NSString *finalKey = [key stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
        //接收值
        NSString *finalValue = [obj stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
        
        
        NSString *part = [NSString stringWithFormat:@"%@ = %@",finalKey,finalValue];
        
        [parts addObject:part];
        
    }];
    
    NSString *queryString = [parts componentsJoinedByString:@"&"];
    
    queryString = queryString ? [NSString stringWithFormat:@"?%@",queryString] : @"";
    
    NSString *pathStr = [NSString stringWithFormat:@"%@?%@",urlStr,queryString];
    
    return pathStr;
    
    
    
}

#pragma mark --根据返回的数据进行统一的格式处理  ----requestData 网络或者是缓存的数据----
+ (void)returnDataWithRequestData:(id )requestData withCompletion: (void (^)(id result))completion{
  
    
    
    //判断是否为字典
    if ([requestData isKindOfClass:[NSError class]]) {
        [self failureEvent:requestData withCompletion:completion];
    }
    
    else
    {
        NSDictionary *  requestDic = (NSDictionary *)requestData;
        //根据返回的接口内容来变
        [self successEvent:requestDic  withCompletion:completion];

    }
    
}

// 网络状态改变
+ (void)reachabilityStatusChange {
    [CNetRequestManager setReachabilityStatusChangeBlock:^(NSInteger status) {
        [MGJRouter openURL:@"yanxi://ReachabilityStatusChange" withUserInfo:@{@"status":@(status)} completion:nil];
    }];
}
//获取网络状态
+ (void)getReachabilityStatus {
    [MGJRouter registerURLPattern:@"yanxi://getReachabilityStatus" toObjectHandler:^id(NSDictionary *routerParameters) {
        
        return @([CNetRequestManager networkReachabilityStatus]);
    }];
}
//设置token
+ (void)setAuthorizationTokenListen {
    
    [MGJRouter registerURLPattern:@"yanxi://SetAuthorizationToken" toHandler:^(NSDictionary *routerParameters) {
        NetCLog(@"设置Token == %@",routerParameters);
        NSDictionary *userInfo = routerParameters[MGJRouterParameterUserInfo];
        [CNetRequestManager setToken:[userInfo.allValues firstObject] withHttpHeader:[userInfo.allKeys firstObject]];
        [MGJRouter openURL:@"yanxi://SetTokenToYYCache" withUserInfo:userInfo completion:nil];
    }];
}
//token 过期 此方法已交由 GeneralNet管理
//+ (void)authorizationTokenInvalid {
//    [MGJRouter openURL:@"msinger://AuthorizationTokenInvalid" withUserInfo:nil completion:nil];
//}

+ (void)successEvent:(NSDictionary*)dict  withCompletion:(void (^)(id result))completion {
    [self successEvent:dict isCache:NO withCacheKey:nil  withCompletion:completion];
}
+ (void)successEvent:(NSDictionary*)dict isCache:(BOOL)isCache withCacheKey:(NSString *)cacheKey withCompletion:(void (^)(id result))completion {
    dispatch_async(dispatch_get_main_queue(), ^{
    
        if (isCache) {
            YYCache *cache =  [self cacheYY];
            [cache setObject:dict forKey:cacheKey];
        }
        if (completion) {
            completion(dict);
        }

//        if([dict[@"code"] intValue]!= 200)
//        {
//            NSError *error = [NSError errorWithDomain:dict[@"msg"] code:[dict[@"code"] intValue] userInfo:nil];
//            if (completion) {
//                completion(error);
//            }
//            
//        }
//        else
//        {
        
//            if (completion) {
//                completion(dict);
//            }
//        }
    });

}
+ (void)failureEvent:(NSError*)error withCompletion:(void (^)(id result))completion {
    dispatch_async(dispatch_get_main_queue(), ^{
         completion(error);
//        for(id object in [[error userInfo] allValues])
//        {
//            
//            if ( [object isMemberOfClass:[NSHTTPURLResponse class]] )
//            {
//                if ([object statusCode] == 401) {
//                    //token 过期；
//                    [self authorizationTokenInvalid];
//                    if (completion) {
//                        completion(error);
//                    }
//                    return ;
//                }
//            }
//        }
//        if (completion) {
//            if (error.code == NSURLErrorCancelled) {
//                return;
//            }
//            NSError *newError = [NSError errorWithDomain:@"服务器请求失败" code:error.code userInfo:error.userInfo];
//            completion(newError);
//        }
    });

}

@end
